package com.tang.group;

import com.tang.lang.Collection;
import com.tang.lang.Iterator;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class GroupStructure implements Collection<Employee, Link> {

    private final String groupId; // 组织ID，也是一个组织链的头部ID
    private final String groupName; // 组织名称
    private final Map<String, Employee> employeeMap = new ConcurrentHashMap<>(); // 雇员列表
    private final Map<String, List<Link>> linkMap = new ConcurrentHashMap<>(); // 组织架构关系
    private final Map<String, String> invertedMap = new ConcurrentHashMap<>(); // 反向关系表

    public GroupStructure(String groupId, String groupName) {
        this.groupId = groupId;
        this.groupName = groupName;
    }

    // 添加雇员
    @Override
    public boolean add(Employee e) {
        return null != employeeMap.put(e.getUId(), e);
    }

    // 删除雇员
    @Override
    public boolean remove(Employee e) {
        return null != employeeMap.remove(e.getUId());
    }

    /**
     * 追加Link
     *
     * @param key  fromId
     * @param link link信息
     * @return true|false
     */
    @Override
    public boolean addLink(String key, Link link) {
        // 倒装map仿佛Link相反数据，通过toId查询出fromId
        invertedMap.put(link.getToId(), link.getFromId());
        if (linkMap.containsKey(key)) {
            // 存在这个key在多给这个Key下的LinkedList加一个Link
            return linkMap.get(key).add(link);
        } else {
            // 不存在就新增一个LinkedList
            List<Link> links = new LinkedList<>();
            links.add(link);
            linkMap.put(key, links);
            return true;
        }
    }

    // 移除key对应的LinkedList
    @Override
    public boolean removeLink(String key) {
        return null == linkMap.remove(key);
    }

    @Override
    public Iterator<Employee> iterator() {
        System.err.println(groupName);
        return new Iterator<Employee>() {
            final Map<String, Integer> keyMap = new HashMap<>();
            int totalIndex = 0; // 当前标志位
            private String fromId = groupId; // 头
            private String toId = groupId; // 下一个

            // 是否有下一个
            @Override
            public boolean hasNext() {
                return totalIndex < employeeMap.size();
            }

            // 找到下一个员工
            @Override
            public Employee next() {
                List<Link> links = linkMap.get(toId);
                int cursorIdx = getCursorIdx(toId);

                // 如果没有下级了，就扫描同级节点扫描
                if (null == links) {
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 上级节点扫描
                while (cursorIdx > links.size() - 1) {
                    fromId = invertedMap.get(fromId);
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 获取节点
                Link link = links.get(cursorIdx);
                fromId = link.getFromId();
                toId = link.getToId();
                totalIndex++;

                return employeeMap.get(link.getToId());
            }

            // 根据toId找低级位
            public int getCursorIdx(String key) {
                int idx = 0;
                if (keyMap.containsKey(key)) {
                    idx = keyMap.get(key);
                    keyMap.put(key, ++idx);
                } else {
                    keyMap.put(key, idx);
                }
                return idx;
            }

        };
    }

}
